package com.ruoyi.wvp.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.enums.DeletedEnum;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.wvp.domain.*;
import com.ruoyi.wvp.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Component("supervisorTask")
@Slf4j
public class SupervisorTask {
    public int count = 0;


    public void insertDutyCount(LocalDate now) {
        count = 0;
//        LocalDate now = LocalDate.now();
        log.info("开始执行分析:{}", now);
        ISurveillanceEventService surveillanceEventService = SpringUtils.getBean(ISurveillanceEventService.class);
        LambdaQueryWrapper<SurveillanceEvent> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(SurveillanceEvent::getSerialNumber,SurveillanceEvent::getEventCode,SurveillanceEvent::getEventBeginTime,SurveillanceEvent::getPicUrl)
                .eq(SurveillanceEvent::getEventTypeStr, "督导员")
                .eq(SurveillanceEvent::getDeleted, DeletedEnum.NOMAL.getValue())
                .ge(SurveillanceEvent::getEventBeginTime, LocalDateTime.of(now, LocalTime.MIN))
                .le(SurveillanceEvent::getEventBeginTime, LocalDateTime.of(now, LocalTime.MAX));
        List<SurveillanceEvent> list = surveillanceEventService.list(wrapper);

        HashMap<String,SurveillanceEvent> serialNumberEventMap = new HashMap<>(list.size());
        for (SurveillanceEvent surveillanceEvent : list) {
            String serialNumber = surveillanceEvent.getSerialNumber();
            SurveillanceEvent event = serialNumberEventMap.get(serialNumber);
            if(Objects.isNull(event)){
                serialNumberEventMap.put(serialNumber,surveillanceEvent);
            }
        }
        Set<String>   serialNumberSet = serialNumberEventMap.keySet();
        log.info("获取已推送督导员记录:{}条", serialNumberSet.size());

        IImageEventService imageEventService = SpringUtils.getBean(IImageEventService.class);
        ImageEvent imageEvent = new ImageEvent();
        imageEvent.setCreateDate(now);
        List<ImageEvent> imageEvents = imageEventService.listAll(imageEvent);
        LinkedList<SurveillanceSupervisor> surveillanceSupervisors = new LinkedList<>();
        for (ImageEvent event : imageEvents) {
            SurveillanceSupervisor supervisor = new SurveillanceSupervisor();
            String picUrl = event.getPicUrl();
            String[] split = picUrl.split("/")[6].split("_");
            String serialNumber = split[0];


            LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(Long.parseLong(split[1]), 0,  ZoneOffset.ofHours(8));
            LocalDate eventBeginTime = localDateTime.toLocalDate();
            if (eventBeginTime.isBefore(now)) {
                continue;
            }
            supervisor.setSerialNumber(serialNumber);
            supervisor.setEventBeginTime(eventBeginTime);
            supervisor.setEventTime(localDateTime);
            supervisor.setPicUrl(picUrl);
            surveillanceSupervisors.add(supervisor);
        }
        Map<String, List<SurveillanceSupervisor>> map = surveillanceSupervisors.stream().collect(Collectors.groupingBy(SurveillanceSupervisor::getSerialNumber));

        ISurveillanceService surveillanceService = SpringUtils.getBean(ISurveillanceService.class);

        LambdaQueryWrapper<Surveillance> queryWrapper = Wrappers.lambdaQuery(Surveillance.class);
        queryWrapper.eq(Surveillance::getDeleted, DeletedEnum.NOMAL.getValue());
        List<Surveillance> surveillanceList = surveillanceService.list(queryWrapper);
        Map<String, List<Surveillance>> collect = surveillanceList.stream().collect(Collectors.groupingBy(Surveillance::getStreetCode));


        LinkedList<SurveillanceSupervisor> addSupervisorList = new LinkedList<>();
        LinkedList<DutyCount> dutyCountList = new LinkedList<>();


        for (Map.Entry<String, List<Surveillance>> stringListEntry : collect.entrySet()) {
            String key = stringListEntry.getKey();
            List<Surveillance> surveillances = collect.get(key);
            if (surveillances == null || surveillances.isEmpty()) {
                log.info("未找到对应街道:{}", key);
                continue;
            }
            DutyCount dutyCount = new DutyCount();
            dutyCount.setCount(0L);
            dutyCount.setTotalCount((long) surveillances.size());
            dutyCount.setCountTime(now);
            Surveillance surveillance = surveillances.get(0);
            dutyCount.setCity(surveillance.getCityCode());
            dutyCount.setStreet(surveillance.getStreetCode());
            dutyCount.setArea(surveillance.getAreaCode());
            dutyCountList.add(dutyCount);
            int notImageEventCount = 0;
            for (Surveillance sur : surveillances) {
                try {
                    if (serialNumberSet.contains(sur.getSerialNumber())) {
                        dutyCount.setCount(dutyCount.getCount() + 1);
                        //有督导员事件
                        SurveillanceEvent surveillanceEvent = serialNumberEventMap.get(sur.getSerialNumber());
                        SurveillanceSupervisor supervisor = new SurveillanceSupervisor();
                        supervisor.setStatus(1);//在岗
                        supervisor.setSerialNumber(sur.getSerialNumber());
                        supervisor.setEventCode(surveillanceEvent.getEventCode());
                        LocalDateTime eventBeginTime = surveillanceEvent.getEventBeginTime();
                        LocalDate localDate=now;
                        if(Objects.nonNull(eventBeginTime)){
                             localDate = eventBeginTime.toLocalDate();
                        }
                        supervisor.setEventBeginTime(localDate);
                        supervisor.setEventTime(surveillanceEvent.getEventBeginTime());
                        supervisor.setPicUrl(surveillanceEvent.getPicUrl());
                        setValueBySurveillance(sur, supervisor);
                        addSupervisorList.add(supervisor);
                        continue;
                    }
                    List<SurveillanceSupervisor> imageList = map.get(sur.getSerialNumber());
                    if (CollectionUtils.isEmpty(imageList)) {
                        dutyCount.setCount(dutyCount.getCount() + 1);
                        notImageEventCount++;
                        SurveillanceSupervisor supervisor = new SurveillanceSupervisor();
                        supervisor.setStatus(1);//在岗  无事件也用在岗
                        supervisor.setSerialNumber(sur.getSerialNumber());
                        supervisor.setEventBeginTime(now);
                        supervisor.setEventTime(null);
                        supervisor.setPicUrl(null);
                        count++;
                        supervisor.setEventCode(now.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + StringUtils.leftPad(count + "", 6, '0'));
                        setValueBySurveillance(sur, supervisor);
                        addSupervisorList.add(supervisor);
                        continue;
                    }
                    int i = new Random().nextInt(imageList.size());
                    SurveillanceSupervisor supervisor = imageList.get(i);
                    if (Objects.isNull(supervisor)) {
                        log.info("获取随机图片失败:{} 设备号:{}", i, sur.getSerialNumber());
                        continue;
                    }
                    count++;
                    supervisor.setEventCode(now.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + StringUtils.leftPad(count + "", 6, '0'));
                    //设置值
                    setValueBySurveillance(sur, supervisor);
                    supervisor.setStatus(0);//未审核
                    addSupervisorList.add(supervisor);
                } catch (Exception e) {
                    log.error("添加错误:{}", e);
                }
            }

            log.info("没有推送图片事件的摄像头数量:{}",notImageEventCount);
        }


        IDutyCountService dutyCountService = SpringUtils.getBean(IDutyCountService.class);
        dutyCountService.saveBatch(dutyCountList);

        ISurveillanceSupervisorService surveillanceSupervisorService = SpringUtils.getBean(ISurveillanceSupervisorService.class);
        surveillanceSupervisorService.saveBatch(addSupervisorList);

        log.info("分析完成:{}", now);
    }

    private static void setValueBySurveillance(Surveillance sur, SurveillanceSupervisor supervisor) {
        supervisor.setCreateBy("系统");
        supervisor.setCreateTime(new Date());
        supervisor.setUpdateBy("系统");
        supervisor.setUpdateTime(new Date());
        supervisor.setSurveillanceId(sur.getId());
        supervisor.setDeviceName(sur.getDeviceName());
        supervisor.setDeviceNumber(sur.getDeviceNumber());
        supervisor.setProviceName(sur.getProviceName());
        supervisor.setProviceCode(sur.getProviceCode());
        supervisor.setCityName(sur.getCityName());
        supervisor.setCityCode(sur.getCityCode());
        supervisor.setAreaName(sur.getAreaName());
        supervisor.setAreaCode(sur.getAreaCode());
        supervisor.setAddress(sur.getAddress());
        supervisor.setCommunity(sur.getCommunity());
        supervisor.setResidentialName(sur.getResidentialName());

        supervisor.setDeviceBrand(sur.getDeviceBrand());
        supervisor.setDeviceModel(sur.getDeviceModel());
        supervisor.setStreetName(sur.getStreetName());
        supervisor.setStreetCode(sur.getStreetCode());
        supervisor.setCommunityCode(sur.getCommunityCode());
        supervisor.setResidentialCode(sur.getResidentialCode());
        supervisor.setRemark(sur.getRemark());
    }

    public void initStart() {
        LocalDate now = LocalDate.now( ZoneOffset.ofHours(8));
        for (int i = 1; i < 16; i++) {
            LocalDate yesterday = now.minusDays(i);
            insertDutyCount(yesterday);
        }
    }

    public void start() {
         LocalDate now = LocalDate.now(ZoneOffset.ofHours(8));
        insertDutyCount(now);
    }


    public void remove() {
        IImageEventService imageEventService = SpringUtils.getBean(IImageEventService.class);
        LocalDate localDate = LocalDate.now().minusMonths(1L);
        log.info("定时任务开始删除imageEvent：{}", localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        LambdaQueryWrapper<ImageEvent> lt = Wrappers.lambdaQuery(ImageEvent.class).lt(ImageEvent::getCreateDate, localDate);
        imageEventService.remove(lt);
        imageEventService.freeSpace();

        log.info("定时任务开始删除wvp_surveillance_supervisor：{}", localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        ISurveillanceSupervisorService surveillanceSupervisorService = SpringUtils.getBean(ISurveillanceSupervisorService.class);
        LambdaQueryWrapper<SurveillanceSupervisor> supervisorWrapper = Wrappers.lambdaQuery(SurveillanceSupervisor.class).lt(SurveillanceSupervisor::getEventBeginTime, localDate);
        surveillanceSupervisorService.remove(supervisorWrapper);
        surveillanceSupervisorService.freeSpace();

    }

}
